package edu.ajb.powersystem.line.parameter.client;

import org.matheclipse.parser.client.eval.ComplexEvaluator;
import org.matheclipse.parser.client.math.Complex;

import com.google.gwt.core.client.EntryPoint;
import java.util.HashMap;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DecoratedTabPanel;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.MenuBar;

public class TransmissionLineParam implements EntryPoint {

	private TextBox txtVline;
	private TextBox txtLineLen;
	private TextBox txtResistance;
	private TextBox txtPhaseSep;
	private TextBox txtBundleSep;
	private TextBox txtDiam;
	private TextBox txtGndHeight;
	private TextBox txtNoCond;
	private TextBox txtCondGMR;
	private TextBox txtInd;
	private TextBox txtCap;
	private TextBox txtInductiveR;
	private TextBox txtCapacitiveR;
	private TextBox txtExactA;
	private TextBox txtExactB;
	private TextBox txtExactC;
	private TextBox txtExactD;
	private TextBox txtExactZ;
	private TextBox txtExactYover2;

	private ListBox comboResUnit;
	private ListBox comboPhaseSepUnit;
	private ListBox comboBundleSepUnit;
	private ListBox comboGndHeightUnit;
	private ListBox comboPhaseConfig;
	private ListBox comboCondGMRUnit;
	private ListBox comboLineUnit;
	private ListBox comboDiamUnit;
	private ListBox comboCapacitiveRUnit;
	private ListBox comboInductiveRUnit;
	private ListBox comboIndUnit;
	private ListBox comboCapUnit;

	private Button btnNominalA;
	private Button btnNominalB;
	private Button btnNominalC;
	private Button btnNominalD;
	private Button btnNominalZ;
	private Button btnNominalYover2;
	private Button btnSolveExact;

	private double inductance; // H/m
	private double inductiveR; // ohm/m
	private double capacitance; // F/m
	private double capacitiveR; // ohm-m

	private ComplexEvaluator engine = new ComplexEvaluator();

	private Complex exactA;
	private Complex exactB;
	private Complex exactC;
	private Complex exactD;
	private Complex exactZ;
	private Complex exactYover2;
	HashMap<Double, String> dataMap;

	private double freq = 60;// Hz

	public void onModuleLoad() {
		initComponents();
	}

	private String formatComplex(Complex z) {
		return ComplexEvaluator.toString(z).replace("I*", "j");
	}

	private void solveExactABCD() {
		computeExactABCD();

		txtExactA.setText("" + formatComplex(exactA));
		txtExactB.setText("" + formatComplex(exactB));
		txtExactC.setText("" + formatComplex(exactC));
		txtExactD.setText("" + formatComplex(exactD));

		txtExactZ.setText("" + formatComplex(exactZ));
		txtExactYover2.setText("" + formatComplex(exactYover2));
	}

	private double convertResistanceUnit(double d, String unit) {
		double result = 0;

		// ohm per given unit
		if (unit.equals("/km")) {
			result = d / 1000;
		} else if (unit.equals("/mi")) {
			result = d / 1609;
		}

		return result;
	}

	private void computeExactABCD() {
		// TODO update unit
		double lineLength = txtLineLen.getText().trim().equals("") ? 0 : Double
				.parseDouble(txtLineLen.getText()); // mi|km
		int N = Integer.parseInt(txtNoCond.getText());
		double res = txtResistance.getText().trim().equals("") ? 0 : Double
				.parseDouble(txtResistance.getText()); // ohms/[mi|km]

		// convert units : line length and resistance
		lineLength = convert2meter(lineLength,
				comboLineUnit.getItemText(comboLineUnit.getSelectedIndex()));
		res = convertResistanceUnit(res,
				comboResUnit.getItemText(comboResUnit.getSelectedIndex()));

		// shunt admittance
		double shuntY = (1.0 / capacitiveR) * lineLength;

		Complex shuntYCmplx = engine.evaluate("I*" + shuntY);

		// series impedance
		double individualRes = res * lineLength / N;
		Complex resCmplx = engine.evaluate("" + individualRes);
		double reactance = inductiveR * lineLength;
		Complex reacCmplx = engine.evaluate("I*" + reactance);
		Complex seriesZCmplx = resCmplx.add(reacCmplx);

		Complex YZ = seriesZCmplx.multiply(shuntYCmplx);
		Complex gammaL = YZ.sqrt();
		Complex ZoverY = seriesZCmplx.divide(shuntYCmplx);
		Complex Zc = ZoverY.sqrt();

		exactA = gammaL.cosh();
		exactB = Zc.multiply(gammaL.sinh());
		exactC = gammaL.sinh().divide(Zc);
		exactD = gammaL.cosh();

		exactZ = Zc.multiply(gammaL.sinh());
		exactYover2 = exactA.subtract(Complex.ONE).divide(exactB);
	}

	private void solveLineParam() {
		// inductance
		computeInductiveReactance();
		txtInd.setText(""
				+ convertUnit(inductance, "H/m", comboIndUnit
						.getItemText(comboIndUnit.getSelectedIndex())));
		txtInductiveR.setText(""
				+ convertUnit(inductiveR, "ohm/m", comboInductiveRUnit
						.getItemText(comboInductiveRUnit.getSelectedIndex())));
		// capacitance
		computeCapacitiveReactance();
		txtCap.setText(""
				+ convertUnit(capacitance, "F/m", comboCapUnit
						.getItemText(comboCapUnit.getSelectedIndex())));
		txtCapacitiveR.setText(""
				+ convertUnit(capacitiveR, "ohm-m", comboCapacitiveRUnit
						.getItemText(comboCapacitiveRUnit.getSelectedIndex())));

		btnSolveExact.setEnabled(true);
	}

	private double convertUnit(double d, String unitFrom, String unitTo) {
		double result = 0;

		if (unitFrom.equals("ohm-m")) {// capacitive reactance
			if (unitTo.equals("Mohm-mi")) {
				result = d / 1609 / 1e6;
			} else if (unitTo.equals("ohm-mi")) {
				result = d / 1609;
			} else if (unitTo.equals("Mohm-km")) {
				result = d / 1000 / 1e6;
			} else if (unitTo.equals("ohm-km")) {
				result = d / 1000;
			} else { // ohm-m
				result = d;
			}
		} else if (unitFrom.equals("F/m")) {// capacitance
			if (unitTo.equals("F/mi")) {
				result = d * 1609;
			} else if (unitTo.equals("F/km")) {
				result = d * 1000;
			} else {
				result = d;
			}
		} else if (unitFrom.equals("ohm/m")) { // inductive reactance
			if (unitTo.equals("ohm/mi")) {
				result = d * 1609;
			} else if (unitTo.equals("ohm/km")) {
				result = d * 1000;
			} else {
				result = d;
			}
		} else if (unitFrom.equals("H/m")) { // inductance
			if (unitTo.equals("H/mi")) {
				result = d * 1609;
			} else if (unitTo.equals("H/km")) {
				result = d * 1000;
			} else {
				result = d;
			}
		}

		return result;
	}

	private void computeCapacitiveReactance() {
		computeCapacitance();

		capacitiveR = 1.0 / (2 * Math.PI * freq * capacitance);
	}

	private void computeCapacitance() {
		double phaseSep = Double.parseDouble(txtPhaseSep.getText());
		double Ds = txtCondGMR.getText().trim().equals("") ? 0 : Double
				.parseDouble(txtCondGMR.getText());
		double diam = txtDiam.getText().trim().equals("") ? 0 : Double
				.parseDouble(txtDiam.getText());
		int N = Integer.parseInt(txtNoCond.getText());
		double S = Double.parseDouble(txtBundleSep.getText());
		double gndHeight = txtGndHeight.getText().trim().equals("") ? 0
				: Double.parseDouble(txtGndHeight.getText());

		// convert to meter
		phaseSep = convert2meter(phaseSep,
				comboPhaseSepUnit.getItemText(comboPhaseSepUnit
						.getSelectedIndex()));
		diam = convert2meter(diam,
				comboDiamUnit.getItemText(comboDiamUnit.getSelectedIndex()));
		Ds = convert2meter(Ds, comboCondGMRUnit.getItemText(comboCondGMRUnit
				.getSelectedIndex()));
		S = convert2meter(S, comboBundleSepUnit.getItemText(comboBundleSepUnit
				.getSelectedIndex()));
		gndHeight = convert2meter(gndHeight,
				comboGndHeightUnit.getItemText(comboGndHeightUnit
						.getSelectedIndex()));

		double epsilon = 8.854e-12;

		double h1 = 0, h2 = 0, h3 = 0;
		double D12 = 0, D23 = 0, D31 = 0;

		String phaseConfig = comboPhaseConfig.getItemText(comboPhaseConfig
				.getSelectedIndex());

		if (phaseConfig.equals("equilateral")) {
			D12 = D23 = D31 = phaseSep;
			if (gndHeight != 0) {
				h1 = h3 = gndHeight;
				h2 = gndHeight
						+ Math.sqrt(Math.pow(phaseSep, 2)
								- Math.pow(phaseSep / 2, 2));
			}
		} else if (phaseConfig.equals("horizontal")) {
			D12 = D23 = phaseSep;
			D31 = 2 * phaseSep;
			if (gndHeight != 0) {
				h1 = h2 = h3 = gndHeight;
			}
		} else {// vertical
			D12 = D23 = phaseSep;
			D31 = 2 * phaseSep;
			if (gndHeight != 0) {
				h1 = gndHeight;
				h2 = gndHeight + phaseSep;
				h3 = gndHeight + 2 * phaseSep;
			}
		}

		double DmDs = lnDmDs(D12, D23, D31, diam / 2, S, N);
		double HmHs = gndHeight == 0 ? 0 : lnHmHs(h1, h2, h3, D31);
		capacitance = 2 * Math.PI * epsilon / (DmDs - HmHs);
	}

	private double lnHmHs(double h1, double h2, double h3, double d31) {
		double H1 = 2 * h1;
		double H2 = 2 * h2;
		double H3 = 2 * h3;

		double H12 = Math.sqrt(Math.pow(H1 + (h2 - h1), 2)
				+ Math.pow(d31 / 2.0, 2));
		double H23 = H12;
		double H31 = Math.sqrt(H1 * H1 + d31 * d31);

		double Hm = Math.cbrt(H12 * H23 * H31);
		double Hs = Math.cbrt(H1 * H2 * H3);

		return Math.log(Hm / Hs);
	}

	private double convert2meter(double d, String unit) {
		double result = 0;

		if (unit.equals("cm")) {
			result = d / 100;
		} else if (unit.equals("in")) {
			result = d * 2.54 / 100;
		} else if (unit.equals("ft")) {
			result = d * 12 * 2.54 / 100;
		} else if (unit.equals("mi")) {
			result = d * 1609;
		} else if (unit.equals("km")) {
			result = d * 1000;
		} else { // m
			result = d;
		}

		return result;
	}

	private void computeInductance() {
		double phaseSep = Double.parseDouble(txtPhaseSep.getText());
		double Ds = txtCondGMR.getText().trim().equals("") ? 0 : Double
				.parseDouble(txtCondGMR.getText());
		double diam = txtDiam.getText().trim().equals("") ? 0 : Double
				.parseDouble(txtDiam.getText());
		int N = Integer.parseInt(txtNoCond.getText());
		double S = Double.parseDouble(txtBundleSep.getText());

		// convert to meter
		phaseSep = convert2meter(phaseSep,
				comboPhaseSepUnit.getItemText(comboPhaseSepUnit
						.getSelectedIndex()));
		diam = convert2meter(diam,
				comboDiamUnit.getItemText(comboDiamUnit.getSelectedIndex()));
		Ds = convert2meter(Ds, comboCondGMRUnit.getItemText(comboCondGMRUnit
				.getSelectedIndex()));
		S = convert2meter(S, comboBundleSepUnit.getItemText(comboBundleSepUnit
				.getSelectedIndex()));

		double Dm = 0;
		String phaseConfig = comboPhaseConfig.getItemText(comboPhaseConfig
				.getSelectedIndex());
		double D12 = 0, D23 = 0, D31 = 0;
		if (phaseConfig.equals("equilateral")) {
			D12 = D23 = D31 = phaseSep;

		} else { // horizontal and vertical
			D12 = D23 = phaseSep;
			D31 = 2 * phaseSep;
		}

		inductance = 2e-7 * lnDmDs(D12, D23, D31, (Ds == 0 ? 0.7788 * diam / 2
				: Ds), S, N);

	}

	private double lnDmDs(double D12, double D23, double D31, double x,
			double S, int N) {
		double Dm = Math.cbrt(D12 * D23 * D31);
		double A = (S / 2.0) / Math.sin(Math.PI / N);
		// (Ds*N*A^(N-1))^1/N
		double Dsb = Math.pow(x * N * Math.pow(A, N - 1), 1.0 / N);

		return Math.log(Dm / Dsb);
	}

	private void computeInductiveReactance() {
		computeInductance();

		inductiveR = 2 * Math.PI * freq * inductance;
	}

	private void initComponents() {
		RootPanel rootPanel = RootPanel.get();

		DecoratedTabPanel paramTabPane = new DecoratedTabPanel();
		paramTabPane.setAnimationEnabled(true);
		rootPanel.add(paramTabPane, 449, 10);
		paramTabPane.setSize("348px", "223px");

		Grid grid_1 = new Grid(5, 3);
		paramTabPane.add(grid_1, "Line Parameter", false);
		grid_1.setSize("366px", "166px");

		Label lblInductance = new Label("Inductance:");
		grid_1.setWidget(0, 0, lblInductance);

		txtInd = new TextBox();
		txtInd.setVisibleLength(22);
		grid_1.setWidget(0, 1, txtInd);

		comboIndUnit = new ListBox();
		comboIndUnit.addItem("H/m");
		comboIndUnit.addItem("H/km");
		comboIndUnit.addItem("H/mi");
		grid_1.setWidget(0, 2, comboIndUnit);

		Label lblInductiveReactance = new Label("Inductive reactance:");
		grid_1.setWidget(1, 0, lblInductiveReactance);

		txtInductiveR = new TextBox();
		txtInductiveR.setVisibleLength(22);
		grid_1.setWidget(1, 1, txtInductiveR);

		comboInductiveRUnit = new ListBox();
		comboInductiveRUnit.addItem("ohm/mi");
		comboInductiveRUnit.addItem("ohm/m");
		comboInductiveRUnit.addItem("ohm/km");
		grid_1.setWidget(1, 2, comboInductiveRUnit);

		Label lblCapacitance = new Label("Capacitance:");
		grid_1.setWidget(2, 0, lblCapacitance);

		txtCap = new TextBox();
		txtCap.setVisibleLength(22);
		grid_1.setWidget(2, 1, txtCap);

		comboCapUnit = new ListBox();
		comboCapUnit.addItem("F/m");
		comboCapUnit.addItem("F/km");
		comboCapUnit.addItem("F/mi");
		grid_1.setWidget(2, 2, comboCapUnit);

		Label lblCapacitiveReactance = new Label("Capacitive reactance:");
		grid_1.setWidget(3, 0, lblCapacitiveReactance);

		txtCapacitiveR = new TextBox();
		txtCapacitiveR.setVisibleLength(22);
		grid_1.setWidget(3, 1, txtCapacitiveR);

		grid_1.getCellFormatter().setHorizontalAlignment(0, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);
		grid_1.getCellFormatter().setHorizontalAlignment(1, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);
		grid_1.getCellFormatter().setHorizontalAlignment(2, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);
		grid_1.getCellFormatter().setHorizontalAlignment(3, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);

		comboCapacitiveRUnit = new ListBox();
		comboCapacitiveRUnit.addItem("Mohm-mi");
		comboCapacitiveRUnit.addItem("ohm-mi");
		comboCapacitiveRUnit.addItem("Mohm-km");
		comboCapacitiveRUnit.addItem("ohm-km");
		comboCapacitiveRUnit.addItem("ohm-m");
		grid_1.setWidget(3, 2, comboCapacitiveRUnit);
		grid_1.getCellFormatter().setHorizontalAlignment(3, 2,
				HasHorizontalAlignment.ALIGN_LEFT);
		grid_1.getCellFormatter().setHorizontalAlignment(2, 2,
				HasHorizontalAlignment.ALIGN_LEFT);
		grid_1.getCellFormatter().setHorizontalAlignment(1, 2,
				HasHorizontalAlignment.ALIGN_LEFT);
		grid_1.getCellFormatter().setHorizontalAlignment(0, 2,
				HasHorizontalAlignment.ALIGN_LEFT);

		Button btnSolveParam = new Button("Solve");
		btnSolveParam.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				solveLineParam();
			}
		});
		grid_1.setWidget(4, 1, btnSolveParam);
		btnSolveParam.setWidth("84px");
		grid_1.getCellFormatter().setHorizontalAlignment(4, 1,
				HasHorizontalAlignment.ALIGN_CENTER);
		grid_1.getCellFormatter().setVerticalAlignment(2, 1,
				HasVerticalAlignment.ALIGN_TOP);
		paramTabPane.selectTab(0);

		DecoratedTabPanel dataTabPane = new DecoratedTabPanel();
		dataTabPane.setAnimationEnabled(true);
		rootPanel.add(dataTabPane, 10, 10);
		dataTabPane.setSize("425px", "439px");

		DockPanel dockPanel = new DockPanel();
		dockPanel.setSpacing(10);
		dataTabPane.add(dockPanel, "Data", false);
		dataTabPane.selectTab(0);
		dockPanel.setSize("389px", "3cm");

		Grid grid = new Grid(10, 3);
		dockPanel.add(grid, DockPanel.CENTER);
		grid.setBorderWidth(0);
		grid.setSize("362px", "372px");

		Label lblNewLabel = new Label("Line voltage:");
		grid.setWidget(0, 0, lblNewLabel);

		txtVline = new TextBox();
		grid.setWidget(0, 1, txtVline);

		Label lblKv = new Label("kV");
		grid.setWidget(0, 2, lblKv);

		Label lblNewLabel_1 = new Label("Line length:");
		lblNewLabel_1.setStyleName("required-label");
		grid.setWidget(1, 0, lblNewLabel_1);

		txtLineLen = new TextBox();
		grid.setWidget(1, 1, txtLineLen);

		comboLineUnit = new ListBox();
		comboLineUnit.addItem("mi");
		comboLineUnit.addItem("km");
		grid.setWidget(1, 2, comboLineUnit);

		Label lblConductorResistance = new Label("Conductor R (ohms):");
		lblConductorResistance.setStyleName("required-label");
		grid.setWidget(2, 0, lblConductorResistance);

		txtResistance = new TextBox();
		grid.setWidget(2, 1, txtResistance);
		grid.getCellFormatter().setVerticalAlignment(1, 0,
				HasVerticalAlignment.ALIGN_MIDDLE);
		grid.getCellFormatter().setHorizontalAlignment(1, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);
		grid.getCellFormatter().setHorizontalAlignment(0, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);
		grid.getCellFormatter().setHorizontalAlignment(2, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);
		grid.getCellFormatter().setVerticalAlignment(2, 0,
				HasVerticalAlignment.ALIGN_MIDDLE);

		comboResUnit = new ListBox();
		comboResUnit.addItem("/mi");
		comboResUnit.addItem("/km");
		grid.setWidget(2, 2, comboResUnit);

		Label lblPhaseSpacing = new Label("Phase spacing:");
		lblPhaseSpacing.setStyleName("required-label");
		grid.setWidget(3, 0, lblPhaseSpacing);
		grid.getCellFormatter().setHorizontalAlignment(3, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);

		txtPhaseSep = new TextBox();
		grid.setWidget(3, 1, txtPhaseSep);

		comboPhaseSepUnit = new ListBox();
		comboPhaseSepUnit.addItem("ft");
		comboPhaseSepUnit.addItem("m");
		grid.setWidget(3, 2, comboPhaseSepUnit);

		Label lblBundleSpacing = new Label("Bundle spacing:");
		lblBundleSpacing.setStyleName("required-label");
		grid.setWidget(4, 0, lblBundleSpacing);
		grid.getCellFormatter().setHorizontalAlignment(4, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);

		txtBundleSep = new TextBox();
		grid.setWidget(4, 1, txtBundleSep);

		comboBundleSepUnit = new ListBox();
		comboBundleSepUnit.addItem("in");
		comboBundleSepUnit.addItem("cm");
		grid.setWidget(4, 2, comboBundleSepUnit);

		Label lblConductorDiam = new Label("Conductor diam.:");
		lblConductorDiam.setStyleName("required-label");
		grid.setWidget(5, 0, lblConductorDiam);
		grid.getCellFormatter().setHorizontalAlignment(5, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);

		txtDiam = new TextBox();
		grid.setWidget(5, 1, txtDiam);

		comboDiamUnit = new ListBox();
		comboDiamUnit.addItem("in");
		comboDiamUnit.addItem("cm");
		grid.setWidget(5, 2, comboDiamUnit);

		Label lblMinGndClearance = new Label("Min. Gnd. Clearance:");
		lblMinGndClearance.setStyleName("required-label");
		grid.setWidget(6, 0, lblMinGndClearance);
		grid.getCellFormatter().setHorizontalAlignment(6, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);

		txtGndHeight = new TextBox();
		txtGndHeight.setText("0");
		grid.setWidget(6, 1, txtGndHeight);

		comboGndHeightUnit = new ListBox();
		comboGndHeightUnit.addItem("ft");
		comboGndHeightUnit.addItem("m");
		grid.setWidget(6, 2, comboGndHeightUnit);

		Label lblPhaseConfiguration = new Label("Phase configuration:");
		lblPhaseConfiguration.setStyleName("required-label");
		grid.setWidget(7, 0, lblPhaseConfiguration);
		grid.getCellFormatter().setHorizontalAlignment(7, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);

		comboPhaseConfig = new ListBox();
		comboPhaseConfig.addItem("equilateral");
		comboPhaseConfig.addItem("horizontal");
		comboPhaseConfig.addItem("vertical");
		grid.setWidget(7, 1, comboPhaseConfig);
		comboPhaseConfig.setWidth("100%");

		Label lblNoConductorsphase = new Label("No. conductors/phase:");
		lblNoConductorsphase.setStyleName("required-label");
		grid.setWidget(8, 0, lblNoConductorsphase);
		grid.getCellFormatter().setHorizontalAlignment(8, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);

		txtNoCond = new TextBox();
		grid.setWidget(8, 1, txtNoCond);

		Label lblConductorGmr = new Label("Conductor GMR:");
		lblConductorGmr.setStyleName("required-label");
		grid.setWidget(9, 0, lblConductorGmr);
		grid.getCellFormatter().setHorizontalAlignment(9, 0,
				HasHorizontalAlignment.ALIGN_RIGHT);

		txtCondGMR = new TextBox();
		grid.setWidget(9, 1, txtCondGMR);

		comboCondGMRUnit = new ListBox();
		comboCondGMRUnit.addItem("ft");
		comboCondGMRUnit.addItem("m");
		grid.setWidget(9, 2, comboCondGMRUnit);
		grid.getCellFormatter().setVerticalAlignment(6, 2,
				HasVerticalAlignment.ALIGN_MIDDLE);
		grid.getCellFormatter().setVerticalAlignment(7, 1,
				HasVerticalAlignment.ALIGN_MIDDLE);
		grid.getCellFormatter().setVerticalAlignment(5, 2,
				HasVerticalAlignment.ALIGN_MIDDLE);
		grid.getCellFormatter().setVerticalAlignment(4, 2,
				HasVerticalAlignment.ALIGN_MIDDLE);
		grid.getCellFormatter().setVerticalAlignment(3, 2,
				HasVerticalAlignment.ALIGN_MIDDLE);
		grid.getCellFormatter().setVerticalAlignment(2, 2,
				HasVerticalAlignment.ALIGN_MIDDLE);
		grid.getCellFormatter().setVerticalAlignment(1, 2,
				HasVerticalAlignment.ALIGN_MIDDLE);
		grid.getCellFormatter().setVerticalAlignment(0, 2,
				HasVerticalAlignment.ALIGN_MIDDLE);
		grid.getCellFormatter().setHorizontalAlignment(0, 2,
				HasHorizontalAlignment.ALIGN_LEFT);
		grid.getCellFormatter().setHorizontalAlignment(1, 2,
				HasHorizontalAlignment.ALIGN_LEFT);
		grid.getCellFormatter().setHorizontalAlignment(2, 2,
				HasHorizontalAlignment.ALIGN_LEFT);
		grid.getCellFormatter().setHorizontalAlignment(3, 2,
				HasHorizontalAlignment.ALIGN_LEFT);
		grid.getCellFormatter().setHorizontalAlignment(4, 2,
				HasHorizontalAlignment.ALIGN_LEFT);
		grid.getCellFormatter().setHorizontalAlignment(5, 2,
				HasHorizontalAlignment.ALIGN_LEFT);
		grid.getCellFormatter().setHorizontalAlignment(6, 2,
				HasHorizontalAlignment.ALIGN_LEFT);
		grid.getCellFormatter().setHorizontalAlignment(9, 2,
				HasHorizontalAlignment.ALIGN_LEFT);

		Label lblAssumeGmdEqual = new Label(
				"Assuming approximate value of GMD. Set zero for ground clearance to exclude earth effect. If conductor GMR is unknown, GMR is set to 0.7788*conductorRadius.");
		lblAssumeGmdEqual.setStyleName("footer-Note");
		dockPanel.add(lblAssumeGmdEqual, DockPanel.SOUTH);
		dockPanel.setCellHorizontalAlignment(lblAssumeGmdEqual,
				HasHorizontalAlignment.ALIGN_CENTER);

		Label lblThreephaseSinglecircuitBundled = new Label(
				"THREE-PHASE, SINGLE-CIRCUIT, SOLID/BUNDLED");
		lblThreephaseSinglecircuitBundled.setStyleName("data-Header");
		dockPanel.add(lblThreephaseSinglecircuitBundled, DockPanel.NORTH);
		dockPanel.setCellVerticalAlignment(lblThreephaseSinglecircuitBundled,
				HasVerticalAlignment.ALIGN_MIDDLE);
		lblThreephaseSinglecircuitBundled.setHeight("19px");
		dockPanel.setCellHorizontalAlignment(lblThreephaseSinglecircuitBundled,
				HasHorizontalAlignment.ALIGN_CENTER);

		DecoratedTabPanel exactTabPane = new DecoratedTabPanel();
		exactTabPane.setAnimationEnabled(true);
		rootPanel.add(exactTabPane, 449, 239);
		exactTabPane.setSize("287px", "126px");

		Grid grid_2 = new Grid(5, 2);
		exactTabPane.add(grid_2, "Exact Line Model", false);
		grid_2.setSize("368px", "3cm");

		Label lblExactA = new Label("A:");
		grid_2.setWidget(0, 0, lblExactA);

		txtExactA = new TextBox();
		txtExactA.setVisibleLength(50);
		grid_2.setWidget(0, 1, txtExactA);

		Label lblExactB = new Label("B:");
		grid_2.setWidget(1, 0, lblExactB);

		txtExactB = new TextBox();
		txtExactB.setVisibleLength(50);
		grid_2.setWidget(1, 1, txtExactB);

		Label lblExactC = new Label("C:");
		grid_2.setWidget(2, 0, lblExactC);

		txtExactC = new TextBox();
		txtExactC.setVisibleLength(50);
		grid_2.setWidget(2, 1, txtExactC);

		Label lblExactD = new Label("D:");
		grid_2.setWidget(3, 0, lblExactD);

		txtExactD = new TextBox();
		txtExactD.setVisibleLength(50);
		grid_2.setWidget(3, 1, txtExactD);

		btnSolveExact = new Button("Solve");
		btnSolveExact.setEnabled(false);
		btnSolveExact.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				solveExactABCD();
			}
		});
		grid_2.setWidget(4, 1, btnSolveExact);
		btnSolveExact.setWidth("89px");
		grid_2.getCellFormatter().setHorizontalAlignment(4, 1,
				HasHorizontalAlignment.ALIGN_CENTER);

		Grid grid_3 = new Grid(2, 2);
		exactTabPane.add(grid_3, "Exact Pi", false);
		grid_3.setSize("5cm", "71px");

		Label lblNewLabel_2 = new Label("Z':");
		grid_3.setWidget(0, 0, lblNewLabel_2);

		txtExactZ = new TextBox();
		txtExactZ.setVisibleLength(50);
		grid_3.setWidget(0, 1, txtExactZ);

		Label lblShuntY = new Label("Y'/2:");
		grid_3.setWidget(1, 0, lblShuntY);

		txtExactYover2 = new TextBox();
		txtExactYover2.setVisibleLength(50);
		grid_3.setWidget(1, 1, txtExactYover2);
		exactTabPane.selectTab(0);

		DecoratedTabPanel nominalTabPane = new DecoratedTabPanel();
		nominalTabPane.setAnimationEnabled(true);
		rootPanel.add(nominalTabPane, 837, 10);
		nominalTabPane.setSize("283px", "146px");
		nominalTabPane.setVisible(false);

		FlowPanel flowPanel = new FlowPanel();
		nominalTabPane.add(flowPanel, "Nominal Line Model", false);
		flowPanel.setSize("253px", "3cm");

		btnNominalA = new Button("Nominal A");
		flowPanel.add(btnNominalA);
		btnNominalA.setEnabled(false);

		btnNominalB = new Button("Nominal B");
		flowPanel.add(btnNominalB);
		btnNominalB.setEnabled(false);

		btnNominalD = new Button("Nominal D");
		flowPanel.add(btnNominalD);
		btnNominalD.setEnabled(false);

		btnNominalC = new Button("Nominal C");
		flowPanel.add(btnNominalC);
		btnNominalC.setEnabled(false);

		btnNominalZ = new Button("Nominal Series Z");
		flowPanel.add(btnNominalZ);
		btnNominalZ.setEnabled(false);

		btnNominalYover2 = new Button("Nominal Shunt Y/2");
		flowPanel.add(btnNominalYover2);
		btnNominalYover2.setEnabled(false);
		nominalTabPane.selectTab(0);
	}
}
